#include <boost/test/unit_test.hpp>
#include "../src/StringFactorization.h"

#include <vector>

#include <boost/tr1/unordered_map.hpp>
#include <boost/dynamic_bitset.hpp>

using namespace std;


BOOST_AUTO_TEST_CASE( StringFactorizationTest )
{
	StringFactorization f(10, 3);
	BOOST_CHECK_EQUAL("A|B|CDEFGHIJ", f.printFactorizedString("ABCDEFGHIJ"));
	f.addBreakpoint(8);
	BOOST_CHECK_EQUAL("A|B|CDEFGHI|J", f.printFactorizedString("ABCDEFGHIJ"));
	f.addBreakpoint(4);
	BOOST_CHECK_EQUAL("A|B|CDE|FGHI|J", f.printFactorizedString("ABCDEFGHIJ"));

	auto_ptr<vector<pair<size_t,size_t> > > intervals = f.getIntervals();
	BOOST_CHECK_EQUAL(5, intervals->size());
	BOOST_CHECK_EQUAL(0, intervals->at(0).first);
	BOOST_CHECK_EQUAL(1, intervals->at(0).second);
	BOOST_CHECK_EQUAL(1, intervals->at(1).first);
	BOOST_CHECK_EQUAL(2, intervals->at(1).second);
	BOOST_CHECK_EQUAL(2, intervals->at(2).first);
	BOOST_CHECK_EQUAL(5, intervals->at(2).second);
	BOOST_CHECK_EQUAL(5, intervals->at(3).first);
	BOOST_CHECK_EQUAL(9, intervals->at(3).second);
	BOOST_CHECK_EQUAL(9, intervals->at(4).first);
	BOOST_CHECK_EQUAL(10, intervals->at(4).second);

}

BOOST_AUTO_TEST_CASE( StringFactorizationInHashMapTest )
{
	typedef boost::dynamic_bitset<> bitset_t;
	typedef std::tr1::unordered_map<StringFactorization, int> map_t;
	map_t map;
	string buffer1 = "0000101001111011";
	string buffer2 = "0101001111011000";
	string buffer3 = "01010011110110000101001111011000010100111101100001010011110110000101001111011000";
	string buffer4 = "01110011110110000101001111011000010100111101100001010011110110000101001111011000";
	bitset_t bs1(buffer1);
	bitset_t bs2(buffer2);
	bitset_t bs3(buffer3);
	bitset_t bs4(buffer4);
	StringFactorization st1(bs1);
	StringFactorization st2(bs2);
	StringFactorization st3(bs3);
	StringFactorization st4(bs4);
	BOOST_CHECK_EQUAL(17, st1.size());
	BOOST_CHECK_EQUAL(17, st2.size());
	BOOST_CHECK_EQUAL(81, st3.size());
	BOOST_CHECK_EQUAL(81, st4.size());
	map[st1] = 7;
	map[st2] = 10;
	map[st3] = 17;
	map[st4] = 18;
	BOOST_CHECK_EQUAL(7, map[st1]);
	BOOST_CHECK_EQUAL(10, map[st2]);
	BOOST_CHECK_EQUAL(17, map[st3]);
	BOOST_CHECK_EQUAL(18, map[st4]);
	BOOST_CHECK(boost::hash_value(st1) != boost::hash_value(st2));
	BOOST_CHECK(boost::hash_value(st3) != boost::hash_value(st4));
	BOOST_CHECK(map.find(st1) != map.end());
	BOOST_CHECK(map.find(st2) != map.end());
	BOOST_CHECK(map.find(st3) != map.end());
	BOOST_CHECK(map.find(st4) != map.end());
	map.erase(st4);
	BOOST_CHECK(map.find(st4) == map.end());
}
